package com.klangner.balls
{
  import flash.geom.Rectangle;
  
  public class CollisionDetector
  {
    private var _bounds:Rectangle;
    private var _balls:Array;
    
    public function CollisionDetector(bounds:Rectangle, balls:Array){
      _bounds = bounds;
      _balls = balls;
    }
    
    public function checkCollision(ball:Ball):Boolean{
      
      if(!checkWalls(ball)){
        return false;
      }
      
      for each(var b:Ball in _balls){
        if(ball != b)
          if(!checkBalls(ball, b))
            return false
      }
      
      return true;
    }

    /**
    * Returns true if no collision
    */
    private function checkWalls(ball:Ball):Boolean{
      
      var radius:Number = ball.radius;
      
      if(ball.x-radius < _bounds.left){
        ball.velocity.x *= -1;
      }else if(ball.x+radius > _bounds.right){
        ball.velocity.x *= -1;
      }else if(ball.y-radius < _bounds.top){
        ball.velocity.y *= -1;
      }else if(ball.y+radius > _bounds.bottom){
        ball.velocity.y *= -1;
      }
      else{
        return true;
      }
      
      return false;
    }
    
    private function checkBalls(ball0:Ball, ball1:Ball):Boolean{
      
      var dx:Number = ball1.x - ball0.x;
      var dy:Number = ball1.y - ball0.y;
      var dist:Number = Math.sqrt(dx*dx + dy*dy);
      if(dist < ball0.radius + ball1.radius)
      {
        // calculate angle, sine, and cosine
        var angle:Number = Math.atan2(dy, dx);
        var sin:Number = Math.sin(angle);
        var cos:Number = Math.cos(angle);

        // rotate ball0's position
        var x0:Number = 0;
        var y0:Number = 0;

        // rotate ball1's position
        var x1:Number = dx * cos + dy * sin;
        var y1:Number = dy * cos - dx * sin;

        // rotate ball0's velocity
        var vx0:Number = ball0.velocity.x * cos + ball0.velocity.y * sin;
        var vy0:Number = ball0.velocity.y * cos - ball0.velocity.x * sin;


        // rotate ball1's velocity
        var vx1:Number = ball1.velocity.x * cos + ball1.velocity.y * sin;
        var vy1:Number = ball1.velocity.y * cos - ball1.velocity.x * sin;
        
        // collision reaction
        var vxTotal:Number = vx0 - vx1;
        vx0 = ((ball0.mass - ball1.mass) * vx0 +
               2 * ball1.mass * vx1) /
               (ball0.mass + ball1.mass);
        vx1 = vxTotal + vx0;
        x0 += vx0;
        x1 += vx1;

        // rotate positions back
        var x0Final:Number = x0 * cos - y0 * sin;
        var y0Final:Number = y0 * cos + x0 * sin;
        var x1Final:Number = x1 * cos - y1 * sin;
        var y1Final:Number = y1 * cos + x1 * sin;

        // adjust positions to actual screen positions
        ball1.x = ball0.x + x1Final;
        ball1.y = ball0.y + y1Final;
        ball0.x = ball0.x + x0Final;
        ball0.y = ball0.y + y0Final;

					  


        // rotate velocities back
        ball0.velocity.x = vx0 * cos - vy0 * sin;
        ball0.velocity.y = vy0 * cos + vx0 * sin;
        ball1.velocity.x = vx1 * cos - vy1 * sin;
        ball1.velocity.y = vy1 * cos + vx1 * sin;
        
        return false;
      }
      
      return true
    }

  }
}